package com.yanqu.road.web.controller.usercenter;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.web.HttpJsonWebParam;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.redis.RedisUserServerList;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.utils.http.HttpHelper;
import com.yanqu.road.web.WebServer;
import com.yanqu.road.web.controller.BaseJsonHttpServlet;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import redis.clients.jedis.Tuple;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.*;

@WebServlet(urlPatterns = "/playerLastedRolesQuery")
public class QueryAccountLastedRoles extends BaseJsonHttpServlet {
    private static Logger logger = LogManager.getLogger(PlayerRoleQuery.class.getName());

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        logger.info("request playerRoleQuery");
        HttpJsonWebParam httpJsonWebParam = super.parseRequest(request);
        JSONObject paramObj = httpJsonWebParam.getParamObj();
        String openId;
        String source_platform;
        int queryType = 0;          //查询类型，0：查全部；1：查最近登录角色
        try{
            openId = paramObj.getString("userID");
            source_platform = paramObj.getString("source_platform");
            queryType = paramObj.getIntValue("queryType");
        }catch (Exception e){
            logger.error("playerRoleQuery argument error:" + e);
            sendResult(response, 0, "argument error");
            return;
        }
        if(WebServer.getInstance().isNeedSend() && Objects.equals(source_platform, "201")){
            // 转发消息到对应的服务器上
            String result = HttpHelper.doPostJson(ChannelConfig.LOGIN_SEND_URL + "playerLastedRolesQuery", paramObj.toJSONString(), "UTF-8");
            sendMessage(response, result);
            return;
        }
        if(queryType == 1){
            Set<Tuple> tupleSet = RedisUserServerList.getPlayerServerListTuple(openId);
            List<Tuple> dataList = new ArrayList<>(tupleSet);
            dataList.sort((o1, o2) -> (int) (o2.getScore() - o1.getScore()));

            JSONObject result = getResultObj(1, "success");
            JSONArray roleList = new JSONArray();
            boolean isFind = false;
            for (Tuple tuple : dataList) {
                long serverId = Long.valueOf(tuple.getElement());
                ServerInfo serverInfo = ServerListMgr.getServerInfo(serverId);
                if (serverInfo == null) {
                    continue;
                }
                if (serverInfo.getServerType() == ServerListMgr.SERVER_TYPE_ACTIVITY) {//三方活动服角色不查
                    continue;
                }

                String roleInfo = "";
                try {
                    roleInfo = HttpHelper.doPostJsonTimeOut(serverInfo.getWebServerUrl() + "/queryUser", paramObj.toJSONString(), "UTF-8", new HashMap<>());
                    JSONObject jsonObject = JSONObject.parseObject(roleInfo);
                    if (jsonObject.getIntValue("state") == 1) {
                        JSONArray jsonArray = JSONArray.parseArray(jsonObject.getJSONObject("data").getString("roleList"));
                        JSONObject lastObj = null;
                        long lastTime = 0;
                        for (Object jo : jsonArray) {
                            JSONObject tempObj = (JSONObject) jo;
                            long lastLoginTime = tempObj.getLongValue("lastLoginTime");
                            if(lastLoginTime > lastTime){
                                lastTime = lastLoginTime;
                                lastObj = tempObj;
                            }
                            ((JSONObject) jo).put("serverId", serverInfo.getServerId());
                        }
                        if(null != lastObj){
                            lastObj.put("serverId", serverInfo.getServerId());
                            roleList.add(lastObj);
                            isFind = true;
                        }
                    }
                } catch (Exception ex) {
                    logger.error("json Array parse error, {} {}", roleInfo, ex.toString());
                }
                if(isFind){
                    break;
                }
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("roleList", roleList);
            result.put("data", jsonObject);
            sendMessage(response, result.toJSONString());
        }else {
            JSONObject result = getResultObj(1, "success");
            JSONArray roleList = new JSONArray();
            List<String> serverIdList = new ArrayList<>(RedisUserServerList.getPlayerServerList(openId));
            // 翻转
            Collections.reverse(serverIdList);
            Map<Long, JSONArray> roleArrayMap = new ConcurrentHashMap<>();
            List<Future> futureList = new ArrayList<>();
            ExecutorService webExecutor = WebServer.getWebExecutor();
            for (int i = 0; i < serverIdList.size(); i++) {
                ServerInfo serverInfo = ServerListMgr.getServerInfo(Integer.valueOf(serverIdList.get(i)));
                if (serverInfo == null) {
                    continue;
                }
                if (serverInfo.getServerType() == ServerListMgr.SERVER_TYPE_ACTIVITY) {//三方活动服角色不查
                    continue;
                }

                Future future = webExecutor.submit(new Callable<Boolean>() {
                    @Override
                    public Boolean call() throws Exception {
                        String roleInfo = "";
                        try {
                            roleInfo = HttpHelper.doPostJsonTimeOut(serverInfo.getWebServerUrl() + "/queryUser", paramObj.toJSONString(), "UTF-8", new HashMap<>());
                            JSONObject jsonObject = JSONObject.parseObject(roleInfo);
                            if (jsonObject.getIntValue("state") == 1) {
                                JSONArray jsonArray = JSONArray.parseArray(jsonObject.getJSONObject("data").getString("roleList"));
                                for (Object jo : jsonArray) {
                                    // 写入服务器id
                                    ((JSONObject) jo).put("serverId", serverInfo.getServerId());
                                }
                                roleArrayMap.put(serverInfo.getServerId(), jsonArray);
                            }
                        } catch (Exception ex) {
                            logger.error("json Array parse error, {} {}", roleInfo, ex.toString());
                        }
                        return true;
                    }
                });
                futureList.add(future);
            }
            if(!futureList.isEmpty()) {
                for (Future future : futureList) {
                    try {
                        boolean ret = (boolean) future.get(2, TimeUnit.SECONDS);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    } catch (TimeoutException e) {
                        e.printStackTrace();
                    }
                }
            }

            for(JSONArray array : roleArrayMap.values()){
                roleList.addAll(array);
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("roleList", roleList);
            result.put("data", jsonObject);
            sendMessage(response, result.toJSONString());
        }
    }
}
